import { useLoginApi } from '@/api/login-api';

/**
 * EncryptUtil 提供加密功能的工具类
 */
export class EncryptUtil {
  /**
   * 使用公钥加密数据 RSA 算法 AES-GCM 模式
   * @param data 需要加密的字符串数据
   * @returns 返回加密后的字符串
   */
  static async encrypt(data) {
    // 获取公钥
    const { data: publicKeyPem } = await useLoginApi().getPublicKey();
    // 导入公钥
    const publicKey = await this.importPublicKey(publicKeyPem);
    // 使用公钥加密数据
    const encryptedMessage = await this.encryptWithPublicKey(publicKey, data);
    // 将加密后的ArrayBuffer转换为base64字符串返回
    return btoa(String.fromCharCode(...new Uint8Array(encryptedMessage)));
  }

  /**
   * 将PEM格式的公钥导入为CryptoKey
   * @param pem PEM格式的公钥字符串
   * @returns 返回导入的CryptoKey
   */
  static async importPublicKey(pem) {
    // 从PEM格式中提取二进制DER字符串
    const binaryDerString = atob(pem.replace(/(-----(BEGIN|END) PUBLIC KEY-----|\n)/g, ''));
    // 将DER字符串转换为Uint8Array
    const binaryDer = Uint8Array.from(binaryDerString, (char) => char.charCodeAt(0));
    // 导入公钥
    return await crypto.subtle.importKey(
      'spki',
      binaryDer.buffer,
      {
        name: 'RSA-OAEP',
        hash: 'SHA-256',
      },
      true,
      ['encrypt']
    );
  }

  /**
   * 使用提供的公钥对数据进行加密
   * @param publicKey CryptoKey类型的公钥
   * @param data 需要加密的字符串数据
   * @returns 返回加密后的ArrayBuffer数据
   */
  static async encryptWithPublicKey(publicKey, data) {
    // 将字符串数据编码为UTF-8的Uint8Array
    const encodedData = new TextEncoder().encode(data);
    // 使用公钥加密数据
    return await crypto.subtle.encrypt(
      {
        name: 'RSA-OAEP',
      },
      publicKey,
      encodedData
    );
  }
}
